package handler

import (
	"github.com/gin-gonic/gin"
	"hcy-api/lib/http"
	"hcy-api/lib/id"
	"hcy-api/structs/enum"
	"hcy-api/structs/lms"
	"hcy-api/structs/tables"
	"lms/global"
	"lms/repository"
	"lms/service"
	"time"
)

var CourseApi = new(courseApi)

type courseApi struct {
}

func (a courseApi) DeleteCourse(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	cour, err := repository.CourseDB.FindById(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	if cour.CreatorId != self.UserID {
		http.BadWithCode(c, enum.ErrorMap.AccessDeniedForCreate)
		return
	}
	err = service.CourseService.DeleteCourse(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a courseApi) PublishCourse(c *gin.Context) {
	var in lms.PublishCourseDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	cour, err := repository.CourseDB.FindById(in.CourseId)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	if cour.CreatorId != self.UserID {
		http.BadWithCode(c, enum.ErrorMap.AccessDeniedForCreate)
		return
	}
	err = service.CourseService.PublishCourse(in)
	if err != nil {
		http.BadWithCode(c, enum.ErrorMap.PublishCourseErr)
		return
	}
	http.OK204(c)
}

func (a courseApi) BindCourseware(c *gin.Context) {
	var in lms.BindCourseware
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	m, err := repository.CourseDB.FindById(in.CourseId)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	if m.CreatorId != self.UserID {
		http.BadWithCode(c, enum.ErrorMap.AccessDeniedForCreate)
		return
	}
	if err := repository.CourseDB.UpdateMapCourseware(in); err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a courseApi) Create(c *gin.Context) {
	var in lms.AddCourse
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	b, err := repository.CourseDB.FindCourseByName(in.Name, in.FolderId)
	if err != nil {
		http.BadWithDB(c, err)
		global.LmsLog.Error(err)
		return
	}
	if b {
		http.BadWithCode(c, enum.ErrorMap.CourseNameExist)
		return
	}
	self := http.GetCurrentUser(c)
	m := &tables.Course{
		Id:             id.GetSnowId(),
		Name:           in.Name,
		Code:           in.Code,
		Cover:          in.Cover,
		Describe:       in.Describe,
		Status:         enum.CourseStatus.Working,
		CourseDuration: 0,
		AllowedX:       in.AllowedX,
		ClassHour:      in.ClassHour,
		ClassScore:     in.ClassScore,
		Label:          in.Label,
		SupportMobile:  in.SupportMobile,
		FolderId:       in.FolderId,
		Sort:           in.Sort,
		AutoCreateInfo: tables.AutoCreateInfo{
			Creator:   self.Nickname,
			CreatorId: self.UserID,
			CreatedAt: time.Now().Unix(),
			UpdatedAt: 0,
			DeletedAt: 0,
		},
	}
	li := make([]tables.MapCourseware, len(in.CoursewareIds))
	for i, v := range in.CoursewareIds {
		li[i] = tables.MapCourseware{
			CourseId:     m.Id,
			CoursewareId: v,
		}
	}
	if err = repository.CourseDB.CreateCourse(m, li); err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, m)
}

func (a courseApi) FindPage(c *gin.Context) {
	var in lms.SearchCourse
	if err := c.ShouldBindQuery(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	self := http.GetCurrentUser(c)
	li, err := service.CourseService.GetCourse(in, self.UserID, self.OrgId)
	total := len(li)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OkPage(c, li, int64(total))
}

func (a courseApi) FolderList(c *gin.Context) {
	li, err := repository.CourseDB.FindFolderList()
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a courseApi) CreateCourseFolder(c *gin.Context) {
	var in lms.AddCourseFolder
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	b, err := repository.CourseDB.FindCourseFolderByName(in.Name, in.ParentId)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	if b {
		http.BadWithCode(c, enum.ErrorMap.CourseFolderNameExist)
		return
	}
	self := http.GetCurrentUser(c)
	m := &tables.CourseFolder{
		FolderId: id.GetSnowId(),
		Name:     in.Name,
		Describe: in.Describe,
		ParentId: in.ParentId,
		Sort:     in.Sort,
		AutoCreateInfo: tables.AutoCreateInfo{
			Creator:   self.Nickname,
			CreatorId: self.UserID,
			CreatedAt: time.Now().Unix(),
			UpdatedAt: 0,
			DeletedAt: 0,
		},
	}
	if err := repository.CourseDB.CreateCourseFolder(m); err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a courseApi) DeleteFolder(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	if in.Id == 1 {
		http.BadWithCode(c, enum.ErrorMap.SysDateNoDelete)
		return
	}
	num, err := repository.CourseDB.CountCourseNumByFolderId(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	if num > 0 {
		http.BadWithCode(c, enum.ErrorMap.ExistCoursewareAboutFolderId)
		return
	}
	err = repository.CourseDB.DeleteFolderById(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}
